Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Closes #122, #123
This PR implements a variant of the approach hashed out in the above issues (with some significant variations), designed to
I'm rather happy with the design including here. It is both cleaner, more correct and (sometimes) faster than what we have in master regarding degeneracy resolution in
bandstructure
.Degeneracies
For context, master deals with d-order degeneracies by keeping d copies of the degenerate eigenvalues, and co-diagonalizing their eigenvectors with some kind of a velocity operator (be it using DualNumbers or finite differences). The codiagonalizer thing was tricky and rather inelegant (somewhat "heuristic" if you're being kind, an ugly hack otherwise). The approach completely failed to give properly connected bands in the presence of Dirac points and/or full band degeneracies (with or without a non-trivial non-Abelian connection). The essential shortcoming is that the codiagonalization approach was an attempt to generalize the 1D
UntangledBands
algorithm in MathQ to a higher-dimensional setting. Which, it turns out, is the wrong way to go about this.The design in this PR takes a different approach that is free of any sort of codiagonalization step. In essence, it keeps degeneracies as single vertices in the bandstructure. Degenerate vertices are associated to a single energy but to a set of eigenstates that form the basis of the degenerate subspace. No attempt is made to choose any specific basis within degenerate subspaces. We stick to what the diagonalizer library produces. Actually, all these subspace basis states are in fact
view
s into the original arrays produced by the diagonalization. Since v1.5 this is allocation-free and very efficient.Extracting the connectivity of a network of eigenpairs that can exhibit degeneracies is a very interesting exercise. It boils down to just two rules:
These two rules produce correct connectivities with any degeneracy configuration that I have tested, including Dirac points, band crossings, Riemann folds and degenerate subbands, as long as the mesh is sufficiently fine to resolve connections through adjacent subspace overlaps.
A consequence of these rules is that any two subbands sharing a degenerate vertex will actually be the same subband. As a result, band folding does no longer split bands into different subbands. Nether do Dirac points, i.e. pi-bands in graphene form a single band that is double-valued on the Brillouin zone.
Preparing for optimized O(1) bandstructure access
An interdependent change is included in this PR. The
mesh
command is renamed once more (it produced conflicts with Makie, in particular). It is now calledcuboid
, which is a special kind of (lazy)CuboidMesh
, different fromBandMesh
, which is more similar to the oldMesh
. Cuboid meshes are marching-tetrahedra meshes over hyper-rectangles (or cuboids) in D-dimensions. All k-point or parameter sampling domains for bandstructures are of this specific kind now. We can still use all the mapping machinery to convert the cuboid to an arbitrary mapped domain, but restricting the base mesh (as it is now called) to a CuboidMesh opens the door to two future improvements:More on that when the time comes. But for now, the user has three things to learn about this change
cuboid
instead ofmesh
subticks
instead ofpoints
for thecuboid
kwarg (points
could be mistaken for the total number of vertices in the mesh, hence the change)cuboid((x1, x2, ... xN), (y1, y2, ... yM)....; kw...)
wherexi
,yi
etc are ticks on thex
,y
axes of the cuboid, such that a vertex will be placed at(xi, yj, zk,...)
for anyi, j, k
combination. Thesubticks
are additional equidistant divisions within each pair of adjacent ticks. In other words, we can still dobut now we can also do
Performance and correctness
The performance of
bandstructure
relative to master is in general rather similar. This PR actually does quite a bit more work than master, although it does so quite a bit more efficiently. The number of allocations, in particular, is drastically reduced. For comparison we have, withh = LatticePresets.honeycomb() |> hamiltonian(hopping(-1)) |> unitcell(2)
master:
(Note the missing simplices around Dirac points)
PR :
(This PR correctly captures the Dirac points)
Other larger systems can actually show a significant performance increase, like this system with subband degeneracies from a project we're working on.
master (timing second run)
(Band degeneracies makes master choke connecting vertices here)
PR (timing second run)
Band degeneracies are handled correctly here. The remaining holes are either inevitable (due to vertices of Riemann folds or Dirac cones that do not fall on a base mesh vertex) or the result of insufficient base mesh resolution at weakly avoided band crossings. The former are essential connectivity frustrations that (I think) can only be resolved by refining the mesh to get the dislocations to fall on a base mesh vertex.
Other details
BandMesh
esSimplices
type) that can be used to efficiently compute density of states and Green's functions in the future.